Frontend.ctrl.ranks = function() {
	var store = {

	// filter default option
	}, _filter = function(self) {
		var i = self,
			s = i.parent().find('span'),
			v = i.val();

		if(v.length > 0) s.hide();
		else s.fadeIn('fast');

	// bind for filter
	}, fields = function() {
		$('input[type="text"]', '#ranks').each(function() {
			var self = $(this);

			_filter(self);
			self.on('input', function(){ _filter(self); });
		});

		$('select', '#ranks').simpleselect();

	// on form submit intercept
	}, intercept = function() {
		// on query submit
		$('form#form_ranks', '#ranks').on('submit', function(e){
			e.preventDefault();

			// find disabled and enable them temporary for form
			var disabled = $(this).find(':input:disabled').removeAttr('disabled'),
				post = $(this).serialize(),
				b = $('button', '#form_ranks');

			// disable them again
			disabled.attr('disabled', 'disabled');

			// for every form field
			$('input[type="text"]', '#form_ranks').each(function() {
				var o = $(this);
					n = o.attr('name'),
					N = n.charAt(0).toUpperCase() + n.substr(1);

				// check if blank
				if(!$.trim(o.val()).length > 0) {
					Frontend.noty({type: 'error', text: N +' is blank'});
					o.addClass('error');
					o.val('');
					_filter(o);
				}
			});

			// check for errors
			var error = false;
			$('input[type="text"]', '#form_ranks').each(function() {
				if($(this).hasClass('error'))
					error = true;
			});

			// stop if errors found
			if(error)
				return false;

			// do ranks procedure
			b.attr('disabled', 'disabled');
			Frontend.ajax({type: 'post', data: post, url: 'ranks/save', success: function(data){
				b.removeAttr('disabled');

				// send message
				Frontend.noty({type: 'success', text: 'Rank was saved!'});

				// go to index
				Frontend.go('ranks');
			}});
		});

	// bind events
	}, bind = function() {
		// on any input change, loose the error
		$('input[type="text"]', '#ranks').on('input', function() {
			$(this).removeClass();
		});

		// on button click
		$('button', 'form.ranks_handlers').on('click', function(e) {
			e.preventDefault();
			var b = $(this);

			// new rank
			if(b.data('handle') == 'new')
				Frontend.go('ranks/create');
		});

		// on drag
		$('div.drag > a', '#ranks').draggable({
			revert: "invalid",
			helper: "clone"
		});

		// on drop
		$('div.drop', '#ranks').droppable({
			activeClass: "active",
			hoverClass: "hover",

			// accept only from different containers
			accept: function(el) {
				return el.data('origin') != $(this).data('id');

			// on drop
			}, drop: function(event, ui) {
				var	self = $(this),
					item = ui.draggable,
					original = item.data('origin'),
					area = self.find('div.drag');

				// do ajax
				Frontend.ajax({type: 'post', data: {id: item.data('id'), to: self.data('id')}, url: 'ranks/move', success: function(data){
					// send message
					Frontend.noty({type: 'success', text: 'User was updated!'});

					// broadcast
					Frontend.socket.rank(data.tokens);

					// set new origin
					item.data('origin', self.data('id'));

					// remove clear
					self.find('div.drag > div.clear').remove();

					// add item
					item.appendTo(area);

					// add clear
					area.append('<div class="clear"></div>');

					// spice it up
					self.flare();
				}});
			}
		});

		// on delete
		$('a.rank_delete', '#ranks').on('click', function(e) {
			e.preventDefault();
			var self = $(this);

			// show confirm
			Frontend.noty({
				type: 'warning',
				text: 'Are you sure?',
				buttons: [{text: 'Yes', onClick: function($noty) {
					$noty.close();

					// do ajax
					Frontend.ajax({type: 'post', data: 'id=' + self.data('id'), url: 'ranks/delete', success: function(data){
						// send message & broadcast
						Frontend.noty({type: 'success', text: 'Rank was deleted!'});
						if(data.changes > 0) {
							Frontend.noty({type: 'warning', text: 'Existing members moved to default rank!'});
							Frontend.socket.rank(data.tokens);
						}

						// redirect
						Frontend.go('ranks');
					}});
				}}, {text: 'No', onClick: function($noty) {
					$noty.close();
				}}]
			});
		});

	// constructor
	}, __construct = function() {
		fields();
		bind();
		intercept();
	};

	// public, yay
	return {
		init: __construct
	};
}();